package rcp.iphex2.ui.heatmapexplorer;

import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;

import org.eclipse.swt.widgets.Display;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYLineAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.RectangleEdge;

import rcp.iphex2.model.AreaAnnotation;
import rcp.iphex2.model.Project;


public class AddAnnotationListener implements ChartMouseListener {
	private JFreeChart chart;
	private XYPlot heatmapPlot;
	private ChartPanel chartPanel;
	private XYLineAnnotation movingtop, movingbot, movingrig, movinglef;
	private double visibleRectRatio = 1.0;
	private Project project;
	private HeatmapExplorerView heatmapExplorerView;

	public AddAnnotationListener(HeatmapExplorerView heatmapExplorerView,ChartPanel chartPanel) {
		super();
		this.heatmapExplorerView = heatmapExplorerView;
		this.chartPanel = chartPanel;
		this.chart = chartPanel.getChart();
		this.heatmapPlot = chart.getXYPlot();
	}

	@Override
	public void chartMouseClicked(ChartMouseEvent arg0) {
		double xViewSize = heatmapPlot.getDomainAxis().getUpperBound()
				- heatmapPlot.getDomainAxis().getLowerBound();

		double yViewSize = heatmapPlot.getRangeAxis().getUpperBound()
				- heatmapPlot.getRangeAxis().getLowerBound();

		double xtol = xViewSize / 40 * visibleRectRatio;
		double ytol = yViewSize / 10 * (2 - visibleRectRatio);

		Point2D p = getXYonChart(arg0.getTrigger());
		double xt = Math.rint(p.getX() * 10000) / 10000.0;
		double yt = Math.rint(p.getY() * 10) / 10.0;
		double k0Tolerance = Math.rint(xtol * 10000) / 10000.0;
		double rtTolerance = Math.rint(ytol * 10) / 10.0;

		String substanceName = "Area (" + xt + "-" + yt + ")";

		final AreaAnnotation areaAnnotation = new AreaAnnotation(substanceName,
				xt, yt, k0Tolerance, rtTolerance);

		Display display = Display.getCurrent();
		if (display == null)
			display = Display.getDefault();
		display.asyncExec(new Runnable() {
			@Override
			public void run() {
				project.addAreaAnnotation(areaAnnotation);
				heatmapExplorerView.updateAnnotations();
			}
		});
	}

	
	@Override
	public void chartMouseMoved(ChartMouseEvent arg0) {
		Point2D p = getXYonChart(arg0.getTrigger());

		double xViewSize = heatmapPlot.getDomainAxis().getUpperBound()
				- heatmapPlot.getDomainAxis().getLowerBound();

		double yViewSize = heatmapPlot.getRangeAxis().getUpperBound()
				- heatmapPlot.getRangeAxis().getLowerBound();

		double xtol = xViewSize / 40 * visibleRectRatio;
		double ytol = yViewSize / 10 * (2 - visibleRectRatio);

		double xt = p.getX();
		double yt = p.getY();

		try {
			heatmapPlot.removeAnnotation(movingtop);
			heatmapPlot.removeAnnotation(movingbot);
			heatmapPlot.removeAnnotation(movinglef);
			heatmapPlot.removeAnnotation(movingrig);
		} catch (Exception exc) {
		}
		movingtop = new XYLineAnnotation(xt - xtol, yt + ytol, xt + xtol, yt
				+ ytol);
		movingbot = new XYLineAnnotation(xt - xtol, yt - ytol, xt + xtol, yt
				- ytol);
		movingrig = new XYLineAnnotation(xt + xtol, yt + ytol, xt + xtol, yt
				- ytol);
		movinglef = new XYLineAnnotation(xt - xtol, yt + ytol, xt - xtol, yt
				- ytol);

		heatmapPlot.addAnnotation(movingtop);
		heatmapPlot.addAnnotation(movingbot);
		heatmapPlot.addAnnotation(movinglef);
		heatmapPlot.addAnnotation(movingrig);

	}

	private Point2D.Double getXYonChart(MouseEvent e) {
		Point2D p = chartPanel.translateScreenToJava2D(e.getPoint());
		PlotOrientation orientation = heatmapPlot.getOrientation();
		RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
				heatmapPlot.getDomainAxisLocation(), orientation);
		RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
				heatmapPlot.getRangeAxisLocation(), orientation);

		ValueAxis domainAxis = heatmapPlot.getDomainAxis();
		ValueAxis rangeAxis = heatmapPlot.getRangeAxis();
		ChartRenderingInfo cri = chartPanel.getChartRenderingInfo();

		PlotRenderingInfo pri = cri.getPlotInfo();
		double x = domainAxis.java2DToValue(p.getX(), pri.getDataArea(),
				domainEdge);
		double y = rangeAxis.java2DToValue(p.getY(), pri.getDataArea(),
				rangeEdge);

		x = Math.rint(x * 10000) / 10000.0;
		y = Math.rint(y * 100) / 100.0;
		return new Point2D.Double(x, y);
	}

	public void setProject(Project project) {
		this.project = project;
	}

}
